#pragma once

#include "Video.h"
#include "Audio.h"

#define  LOG_TAG   "TS_MUX"
#define  LOGI(...)  do { } while (0)

struct MuxItem
{
	Continuity_Counter continuity_counter;      // 包类型计数器
	int isInsertPatPmt;

	unsigned char m_One_Frame_Buf[MAX_ONE_FRAME_SIZE];
	TsPes m_video_tspes;
	TsPes m_audio_tspes;
	unsigned int WritePacketNum;                // 一共的包数目
	unsigned long long Timestamp_video;             // 一帧视频所用时间
	unsigned long long Timestamp_audio;             // 一帧音频所用时间
	unsigned char uVideoEncType;				// 视频编码类型 h264=0 h265=1

	int            bHasAudioPid;                // 是否含有音频 PID（发送 PMT 时决定是否填充音频信息，视频必含）

	MuxItem()
	{
		isInsertPatPmt = 0;
		memset(m_One_Frame_Buf, 0, MAX_ONE_FRAME_SIZE);
		WritePacketNum = 0;
		Timestamp_video = 0;
		Timestamp_audio = 0;
		bHasAudioPid = 0;
		uVideoEncType = 0;
	}
};

enum EStreamType
{
	ESTREAM_AUDIO = 0,
	ESTREAM_VIDEO = 1,
};

struct IMuxOutput
{
	virtual ~IMuxOutput() {}
	virtual int OnTsPacket(unsigned char *lpszBuf, int nLen, long long lTimestamp) = 0;
	virtual MuxItem* GetMuxItem() = 0;
};

int Write_Pat(unsigned char * buf, IMuxOutput *pOutput);
int Write_Pmt(unsigned char * buf, IMuxOutput *pOutput);
int Take_Out_Pes(TsPes * tspes, unsigned long time_pts, unsigned int frametype, unsigned int *videoframetype, unsigned char *pData, int iDataSize, unsigned char uVideoEncType);

int WriteAdaptive_flags_Head(Ts_Adaptation_field  * ts_adaptation_field,unsigned int Videopts);
int WriteAdaptive_flags_Tail(Ts_Adaptation_field  * ts_adaptation_field);

int WriteBuf2TsFile(unsigned int framerate,EStreamType eStreamType,unsigned char *pData,int iDataSize,unsigned long long lTimeStamp,int type, IMuxOutput *pOutput);

int PES2TS(TsPes * ts_pes,unsigned int Video_Audio_PID ,Ts_Adaptation_field * ts_adaptation_field_Head ,Ts_Adaptation_field * ts_adaptation_field_Tail,
		   unsigned long  Videopts,unsigned long Adudiopts, IMuxOutput *pOutput);

int CreateAdaptive_Ts(Ts_Adaptation_field * ts_adaptation_field,unsigned char * buf,unsigned int AdaptiveLength);
